/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package giuliani_mapelli_marocco.boundary;

import giuliani_mapelli_marocco.business.UserManager;
import giuliani_mapelli_marocco.business.EventManager;
import giuliani_mapelli_marocco.business.MessageManager;
import giuliani_mapelli_marocco.business.TimeTools;
import giuliani_mapelli_marocco.entity.Event;
import giuliani_mapelli_marocco.entity.User;
import giuliani_mapelli_marocco.enumerations.InternalMessageType;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.ejb.EJBException;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.view.ViewScoped;
import javax.inject.Named;

@Named
@ViewScoped
public class EventBean implements Serializable {

    @EJB
    EventManager em;
    
    @EJB 
    UserManager um;
    
    @EJB
    MessageManager mm;
    
    private Event event;
    private List<User> invitedPeople;
    private List<User> justInvitedPeople;
    private List<User> participantPeople;
    private String newUserInvited;
    private Date currentDate = new Date();


    public EventBean() {
        invitedPeople = new ArrayList();
        justInvitedPeople = new ArrayList();
    }
    
    /**
     * Initializes the bean using the "idEvent" parameter.
     */
    @PostConstruct
    public void init() {
        FacesContext context = FacesContext.getCurrentInstance();
        String idEvent = context.getExternalContext()
                    .getRequestParameterMap().get("idEvent");
        if(idEvent != null) {
            event = em.findEventById( Long.valueOf(idEvent));
            invitedPeople= (List<User>) event.getUserCollection();
            participantPeople = (List<User>) event.getUserCollection1();
        }
    }
    
    public Date getCurrentDate() {
    return currentDate;
}
   
    public Event getEvent() {
        if (event == null) {
            event = new Event();
        }
        return event;
    }

    public void setEvent(Event event) {
        this.event = event;
    }
    
    public String getNewUserInvited() {
        return newUserInvited;
    }

    public void setNewUserInvited(String newUserInvited) {
        this.newUserInvited = newUserInvited;
    }
    
    
    public List<User> getInvitedPeople() {
        return invitedPeople;
    }

    public void setInvitedPeople(List<User> invitedPeople) {
        this.invitedPeople = invitedPeople;
    }

    public List<User> getJustInvitedPeople() {
        return justInvitedPeople;
    }

    public void setJustInvitedPeople(List<User> justInvitedPeople) {
        this.justInvitedPeople = justInvitedPeople;
    }

    public List<User> getParticipantPeople() {
        return participantPeople;
    }

    public void setParticipantPeople(List<User> participantPeople) {
        this.participantPeople = participantPeople;
    }
    
    /**
     * Given a date, it returns its date formatted
     * @param date date
     * @return the formatted date string
     */
    public String getFormattedDate(Date date) {
        String formattedDate = TimeTools.convertDateToString(date);
        return formattedDate;
    }
    
    public void addInvitedUser()  {
        User user;
        try {
            user = um.findUserByUsername(newUserInvited);
            String validityMessage= em.checkInvitationValidity(event, invitedPeople, newUserInvited, um.getLoggedUser().getUsername());
            if( !validityMessage.equals(InternalMessageType.NO_ERRORS.getMessageContent())) {
                FacesContext context = FacesContext.getCurrentInstance();
                context.addMessage(null, new FacesMessage(validityMessage,  "") );
                return;
            }
            invitedPeople.add(user);
            justInvitedPeople.add(user);
            
       } catch(EJBException e) {
        FacesContext context = FacesContext.getCurrentInstance();
        context.addMessage(null, new FacesMessage("The user does not exist",  "") );
       }
    }
    
    /**
     * Allows the user to withdraw an invitation that he was going to send to "userToBeRemoved"
     * @param userToBeRemoved username of the user you no longer wish to invite
     */
    public void withdrawInvitation(String userToBeRemoved) {
        User user;
        try {
            user = um.findUserByUsername(userToBeRemoved);
        } catch(EJBException e) {
            FacesContext context = FacesContext.getCurrentInstance();
            context.addMessage(null, new FacesMessage("You haven't selected any invited user.",  ""));
            return;
        }
        invitedPeople.remove(user);
        justInvitedPeople.remove(user);
    }

    public String registerEvent() {
        event.setDeleted(false);
        event.setOrganizer(um.getLoggedUser());
        ArrayList<User> participantsList= new ArrayList();
        participantsList.add(um.getLoggedUser());
        event.setUserCollection1(participantsList);
        event.setUserCollection(invitedPeople);
        String eventManagerMessage = em.checkTimeFieldsValidity(event, um.getLoggedUser());
        if( !eventManagerMessage.equals(InternalMessageType.NO_ERRORS.getMessageContent())) {
            FacesContext context = FacesContext.getCurrentInstance();
            context.addMessage(null, new FacesMessage(eventManagerMessage,  "please change time"));
            return null;
        }
        em.save(event);        
        return "/user/home?faces-redirect=true";
    }
    
    /**
     * allows the user to submit event changes
     * @return the next page to navigate to
     */
    public String submitModifications() {
        event.setUserCollection(invitedPeople);
        String eventManagerMessage = em.checkTimeFieldsValidity(event, um.getLoggedUser());
        if( !eventManagerMessage.equals(InternalMessageType.NO_ERRORS.getMessageContent())) {
            FacesContext context = FacesContext.getCurrentInstance();
            context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, eventManagerMessage,  "please change time"));
            return null;
        }
        if (em.eventAlreadyStarted(event)) {
            FacesContext context = FacesContext.getCurrentInstance();
            context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, InternalMessageType.EVENT_ALREADY_STARTED.getMessageContent(),  ""));
            return null;
        }
        em.modifyEvent(event, justInvitedPeople);
        FacesContext context = FacesContext.getCurrentInstance();
        context.addMessage(null, new FacesMessage(InternalMessageType.MODIFY_EVENT_SUCCESSFUL.getMessageContent(), ""));
        return "/user/home?faces-redirect=true";
    }
    
    /**
     * Allows the user to delete the event from his calendar
     * @return the next web page to navigate to
     */
    public String deleteEvent() {
        em.delete(event);
        return "/user/home?faces-redirect=true";
    }
    
    /**
     * Allows the user to accept the invitation to the event that he's been invited to
     * @return the next web page to navigate to
     */
    public String acceptInvitation() {
        String message = mm.acceptInvitation(event, um.getLoggedUser());
        if(!(message.equals(InternalMessageType.INVITATION_ACCEPTED.getMessageContent()))) {
            FacesContext context = FacesContext.getCurrentInstance();
            context.addMessage(null, new FacesMessage(message,  ""));
            return null;
        }
        return "/user/home?faces-redirect=true";
    }
    
    /**
     * Allows the user to decline the invitation to the event that he's been invited to
     * @return the next web page to navigate to
     */
    public String declineInvitation() {
        mm.declineInvitation(event, um.getLoggedUser());
        return "/user/home?faces-redirect=true";
    }
    
    /**
     * Allows the user to declare that he won't partecipate to the event
     * @return the next web page to navigate to
     */
    public String declineParticipation() {
        String message = em.withdrawEventParticipation(event, um.getLoggedUser());
        if((message.equals(InternalMessageType.CANNOT_DELETE_PARTICIPATION.getMessageContent()))) {
            FacesContext context = FacesContext.getCurrentInstance();
            context.addMessage(null, new FacesMessage(message,  ""));
            return null;
        }
        return "/user/home?faces-redirect=true";
    }
    
    /**
     * Checks whethere the event is already started
     * @return true if the event is already started, false otherwise
     */
    public boolean isAlreadyStarted() {
        return em.eventAlreadyStarted(event);
}
}
